﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NAudio.Wave;
using System.Net.Sockets;
using System.Net;

namespace NotifierService.Client
{
    internal class AudioTransmitter
    {
        #region Fields

        private WaveIn _waveIn;
        private IAudioCodec _audioCodec;
        private UdpClient _udpSender;
        private volatile bool _isConnected;
        private bool _isIPv6Connection;
        private IPEndPoint _remoteEndPoint;

        public AudioTransmitter(bool isIPv6 = false)
        {
            _audioCodec = new UltraWideBandSpeexCodec();
            _isIPv6Connection = isIPv6;
        }

        public void Connect(string ipAddr, int port)
        {
            var endPoint = new IPEndPoint(System.Net.IPAddress.Parse(ipAddr), port);
            Connect(endPoint);
        }

        public void Connect(IPAddress ipAddr, int port)
        {
            Connect(new IPEndPoint(ipAddr, port));
        }

        public void Connect(IPEndPoint endPoint)
        {
            PrivateConnect(endPoint, 0, _audioCodec);
        }

        private void PrivateConnect(System.Net.IPEndPoint endPoint, int inputDeviceNumber, IAudioCodec codec)
        {
            if (_isConnected)
                throw new InvalidOperationException("This notifier has already been working.");

            _remoteEndPoint = endPoint;

            _waveIn = new WaveIn();
            _waveIn.BufferMilliseconds = 50;
            _waveIn.DeviceNumber = inputDeviceNumber;
            _waveIn.WaveFormat = codec.RecordFormat;
            _waveIn.DataAvailable += WaveIn_DataAvailable;
            _waveIn.StartRecording();

            _udpSender = new UdpClient(_isIPv6Connection ? AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork);
            //_udpSender.Connect(endPoint);

            _isConnected = true;

        }

        private void WaveIn_DataAvailable(object sender, WaveInEventArgs e)
        {
            var encoded = _audioCodec.Encode(e.Buffer, 0, e.BytesRecorded);
            _udpSender.Send(encoded, encoded.Length, _remoteEndPoint);
        }

        #endregion
    }
}
